home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / src_1218.zip / SOCKET.C < prev    next >
C/C++ Source or Header  |  1991-01-27  |  47KB  |  1,984 lines

  1. /* Application programming interface routines - based loosely on the
  2.  * "socket" model in Berkeley UNIX.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #ifdef    __STDC__
  8. #include <stdarg.h>
  9. #endif
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "netuser.h"
  13. #include "timer.h"
  14. #include "iface.h"
  15. #include "ip.h"
  16. #include "tcp.h"
  17. #include "udp.h"
  18. #include "ax25.h"
  19. #include "lapb.h"
  20. #include "netrom.h"
  21. #include "nr4.h"
  22. #include "proc.h"
  23. #include "lzw.h"
  24. #include "usock.h"
  25. #include "socket.h"
  26. #include "config.h"
  27.  
  28. static void autobind __ARGS((int s,int af));
  29. static int checkaddr __ARGS((int type,char *name,int namelen));
  30. static void rip_recv __ARGS((struct raw_ip *rp));
  31. static void s_trcall __ARGS((struct tcb *tcb,int cnt));
  32. static void s_tscall __ARGS((struct tcb *tcb,int old,int new));
  33. static void s_ttcall __ARGS((struct tcb *tcb,int cnt));
  34. static void s_urcall __ARGS((struct iface *iface,struct udp_cb *udp,int cnt));
  35. static void trdiscard __ARGS((struct tcb *tcb,int cnt));
  36. #ifdef    NETROM
  37. static void s_nrcall __ARGS((struct nr4cb *cb,int cnt));
  38. static void s_nscall __ARGS((struct nr4cb *cb,int old,int new));
  39. static void s_ntcall __ARGS((struct nr4cb *cb,int cnt));
  40. #endif
  41.  
  42. static int16 Lport = 1024;
  43.  
  44. char *Socktypes[] = {
  45.     "Not Used",
  46.     "TCP",
  47.     "UDP",
  48.     "AX25 I",
  49.     "AX25 UI",
  50.     "Raw IP",
  51.     "NETROM3",
  52.     "NETROM",
  53.     "Loc St",
  54.     "Loc Dg"
  55. };
  56. char Badsocket[] = "Bad socket";
  57. struct usock *Usock;        /* Socket entry array */
  58. int Nusock = DEFNSOCK;        /* Number of socket entries */
  59.  
  60. /* The following two variables are needed because there can be only one
  61.  * socket listening on each of the AX.25 modes (I and UI)
  62.  */
  63. #ifdef    AX25
  64. int Axi_sock = -1;    /* Socket number listening for AX25 connections */
  65. static int Axui_sock = -1;    /* Socket number listening for AX25 UI frames */
  66. static struct mbuf *Bcq;    /* Queue of incoming UI frames */
  67.  
  68. /* Function that handles incoming UI frames from lapb.c */
  69. void
  70. beac_input(iface,src,bp)
  71. struct iface *iface;
  72. char *src;
  73. struct mbuf *bp;
  74. {
  75.     struct mbuf *hdr;
  76.     struct sockaddr_ax *sax;
  77.  
  78.     if(Axui_sock == -1){
  79.         /* Nobody there to read it */
  80.         free_p(bp);
  81.     } else {
  82.         if((hdr = pushdown(NULLBUF,sizeof(struct sockaddr_ax))) == NULLBUF){
  83.             free_p(bp);
  84.             return;
  85.         }
  86.         sax = (struct sockaddr_ax *)hdr->data;
  87.         sax->sax_family = AF_AX25;
  88.         memcpy(sax->ax25_addr,src,AXALEN);
  89.         strncpy(sax->iface,iface->name,ILEN);
  90.         hdr->next = bp;
  91.         enqueue(&Bcq,hdr);
  92.     }
  93. }
  94. #endif
  95.  
  96. /* Initialize user socket array */
  97. void
  98. sockinit()
  99. {
  100.     if(Usock != NULLUSOCK)
  101.         return;    /* Already initialized */
  102.     Usock = (struct usock *)callocw(Nusock,sizeof(struct usock));
  103. }
  104.  
  105. /* Create a user socket, return socket index
  106.  * The mapping to actual protocols is as follows:
  107.  *        
  108.  *        
  109.  * ADDRESS FAMILY    Stream        Datagram    Raw        Seq. Packet
  110.  *
  111.  * AF_INET        TCP        UDP        IP
  112.  * AF_AX25        I-frames    UI-frames
  113.  * AF_NETROM                        NET/ROM L3  NET/ROM L4
  114.  * AF_LOCAL        stream loopback    packet loopback
  115.  */
  116. int
  117. socket(af,type,protocol)
  118. int af;        /* Address family */
  119. int type;    /* Stream or datagram */
  120. int protocol;    /* Used for raw IP sockets */
  121. {
  122.     register struct usock *up;
  123.     int s;
  124.  
  125.     for(up=Usock;up < &Usock[Nusock];up++)
  126.         if(up->type == NOTUSED)
  127.             break;
  128.  
  129.     if(up == &Usock[Nusock]){
  130.         /* None left */
  131.         errno = EMFILE;
  132.         return -1;
  133.     }
  134.     up->refcnt = 1;
  135.     s = up - Usock + SOCKBASE;
  136.     errno = 0;
  137.     up->noblock = 0;
  138.     up->rdysock = -1;
  139.     up->cb.p = NULLCHAR;
  140.     up->peername = up->name = NULLCHAR;
  141.     up->namelen = up->peernamelen = 0;
  142.     up->owner = Curproc;
  143.     up->obuf = NULLBUF;
  144.     memset(up->errcodes,0,sizeof(up->errcodes));
  145.     memset(up->eol,0,sizeof(up->eol));
  146.     up->flush = '\n';    /* default is line buffered */
  147.     switch(af){
  148.     case AF_LOCAL:
  149.         up->cb.local = (struct loc *) callocw(1,sizeof(struct loc));
  150.         up->cb.local->peer = up;    /* connect to self */
  151.         switch(type){
  152.         case SOCK_STREAM:
  153.             up->type = TYPE_LOCAL_STREAM;
  154.             up->cb.local->hiwat = LOCSFLOW;
  155.             break;
  156.         case SOCK_DGRAM:
  157.             up->type = TYPE_LOCAL_DGRAM;
  158.             up->cb.local->hiwat = LOCDFLOW;
  159.             break;
  160.         default:
  161.             free(up->cb.local);
  162.             errno = ESOCKTNOSUPPORT;
  163.             break;
  164.         }
  165.         break;
  166. #ifdef    AX25
  167.     case AF_AX25:
  168.         switch(type){
  169.         case SOCK_STREAM:
  170.             up->type = TYPE_AX25I;
  171.             break;
  172.         case SOCK_DGRAM:
  173.             up->type = TYPE_AX25UI;
  174.             break;
  175.         default:
  176.             errno = ESOCKTNOSUPPORT;
  177.             break;
  178.         }
  179.         strcpy(up->eol,AX_EOL);
  180.         break;
  181. #endif
  182. #ifdef NETROM
  183.     case AF_NETROM:
  184.         switch(type){
  185.         case SOCK_RAW:
  186.             up->type = TYPE_NETROML3;
  187.             up->cb.rnr = raw_nr((char)protocol);
  188.             break;
  189.         case SOCK_SEQPACKET:
  190.             up->type = TYPE_NETROML4;
  191.             break;
  192.         default:
  193.             errno = ESOCKTNOSUPPORT;
  194.             break;
  195.         }
  196.         strcpy(up->eol,AX_EOL);
  197.         break;
  198. #endif
  199.     case AF_INET:
  200.         switch(type){
  201.         case SOCK_STREAM:
  202.             up->type = TYPE_TCP;
  203.             strcpy(up->eol,INET_EOL);
  204.             break;
  205.         case SOCK_DGRAM:
  206.             up->type = TYPE_UDP;
  207.             break;
  208.         case SOCK_RAW:
  209.             up->type = TYPE_RAW;
  210.             up->cb.rip = raw_ip(protocol,rip_recv);
  211.                         up->cb.rip->user = s;
  212.             break;
  213.         default:
  214.             errno = ESOCKTNOSUPPORT;
  215.             break;
  216.         }
  217.         break;
  218.     default:
  219.         errno = EAFNOSUPPORT;
  220.         break;
  221.     }
  222.     if(errno)
  223.         return -1;
  224.  
  225.     return s;
  226. }
  227.  
  228. /* Attach a local address/port to a socket. If not issued before a connect
  229.  * or listen, will be issued automatically
  230.  */
  231. int
  232. bind(s,name,namelen)
  233. int s;        /* Socket index */
  234. char *name;    /* Local name */
  235. int namelen;    /* Length of name */
  236. {
  237.     register struct usock *up;
  238.     union sp local;
  239.     struct socket lsock;
  240.  
  241.     if((up = itop(s)) == NULLUSOCK){
  242.         errno = EBADF;
  243.         return -1;
  244.     }
  245.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  246.         errno = EINVAL;
  247.         return -1;
  248.     }
  249.     if(name == NULLCHAR){
  250.         errno = EFAULT;
  251.         return -1;
  252.     }
  253.     if(up->name != NULLCHAR){
  254.         /* Bind has already been issued */
  255.         errno = EINVAL;
  256.         return -1;
  257.     }
  258.     if(checkaddr(up->type,name,namelen) == -1){
  259.         /* Incorrect length or family for chosen protocol */
  260.         errno = EAFNOSUPPORT;
  261.         return -1;    
  262.     }
  263.     /* Stash name in an allocated block */
  264.     up->namelen = namelen;
  265.     up->name = mallocw(namelen);
  266.     memcpy(up->name,name,namelen);
  267.     /* Create control block for datagram sockets */
  268.     switch(up->type){
  269.     case TYPE_UDP:
  270.         local.in = (struct sockaddr_in *)up->name;
  271.         lsock.address = local.in->sin_addr.s_addr;
  272.         lsock.port = local.in->sin_port;
  273.         up->cb.udp = open_udp(&lsock,s_urcall);
  274.         up->cb.udp->user = s;
  275.         break;
  276. #ifdef    AX25
  277.     case TYPE_AX25UI:
  278.         if(Axui_sock != -1){
  279.             errno = EADDRINUSE;
  280.             return -1;
  281.         }
  282.         Axui_sock = s;
  283.         break;
  284. #endif
  285.     }
  286.     return 0;
  287. }
  288. /* Post a listen on a socket */
  289. int
  290. listen(s,backlog)
  291. int s;        /* Socket index */
  292. int backlog;    /* 0 for a single connection, 1 for multiple connections */
  293. {
  294.     register struct usock *up;
  295.     union sp local;
  296.     struct socket lsock;
  297.  
  298.     if((up = itop(s)) == NULLUSOCK){
  299.         errno = EBADF;
  300.         return -1;
  301.     }
  302.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  303.         errno = EINVAL;
  304.         return -1;
  305.     }
  306.     if(up->cb.p != NULLCHAR){
  307.         errno = EISCONN;
  308.         return -1;
  309.     }
  310.     switch(up->type){
  311.     case TYPE_TCP:
  312.         if(up->name == NULLCHAR)
  313.             autobind(s,AF_INET);
  314.  
  315.         local.in = (struct sockaddr_in *)up->name;
  316.         lsock.address = local.in->sin_addr.s_addr;
  317.         lsock.port = local.in->sin_port;
  318.         up->cb.tcb = open_tcp(&lsock,NULLSOCK,
  319.          backlog ? TCP_SERVER:TCP_PASSIVE,0,
  320.         s_trcall,s_ttcall,s_tscall,0,s);
  321.         break;
  322. #ifdef AX25
  323.     case TYPE_AX25I:
  324.         if(up->name == NULLCHAR)
  325.             autobind(s,AF_AX25);
  326.         if(s != Axi_sock){
  327.             errno = EOPNOTSUPP;
  328.             return -1;
  329.         }
  330.         local.ax = (struct sockaddr_ax *)up->name;
  331.         up->cb.ax25 = open_ax25(NULLIF,local.ax->ax25_addr,NULLCHAR,
  332.          backlog ? AX_SERVER:AX_PASSIVE,0,
  333.          s_arcall,s_atcall,s_ascall,s);
  334.         break;
  335. #endif
  336. #ifdef NETROM
  337.     case TYPE_NETROML4:
  338.         if(up->name == NULLCHAR)
  339.             autobind(s,AF_NETROM);
  340.         local.nr = (struct sockaddr_nr *)up->name;
  341.         up->cb.nr4 = open_nr4(&local.nr->nr_addr,NULLNRADDR,
  342.          backlog ? AX_SERVER:AX_PASSIVE,
  343.          s_nrcall,s_ntcall,s_nscall,s);
  344.         break;
  345. #endif
  346.     default:
  347.         /* Listen not supported on datagram sockets */
  348.         errno = EOPNOTSUPP;
  349.         return -1;        
  350.     }
  351.     return 0;
  352. }
  353. /* Initiate active open. For datagram sockets, merely bind the remote address. */
  354. int
  355. connect(s,peername,peernamelen)
  356. int s;            /* Socket index */
  357. char *peername;        /* Peer name */
  358. int peernamelen;    /* Length of peer name */
  359. {
  360.     register struct usock *up;
  361.     union cb cb;
  362.     union sp local,remote;
  363.     struct socket lsock,fsock;
  364. #ifdef    AX25
  365.     struct iface *iface;
  366. #endif
  367.  
  368.     if((up = itop(s)) == NULLUSOCK){
  369.         errno = EBADF;
  370.         return -1;
  371.     }
  372.     if(up->type == TYPE_LOCAL_DGRAM || up->type == TYPE_LOCAL_STREAM){
  373.         errno = EINVAL;
  374.         return -1;
  375.     }
  376.     if(peername == NULLCHAR){
  377.         /* Connect must specify a remote address */
  378.         errno = EFAULT;
  379.         return -1;
  380.     }
  381.     if(checkaddr(up->type,peername,peernamelen) == -1){
  382.         errno = EAFNOSUPPORT;
  383.         return -1;
  384.     }
  385.     /* Raw socket control blocks are created in socket() */
  386.     if(up->type != TYPE_RAW && up->type != TYPE_NETROML3 &&
  387.        up->cb.p != NULLCHAR){
  388.         errno = EISCONN;
  389.         return -1;
  390.     }
  391.     up->peername = mallocw(peernamelen);
  392.     memcpy(up->peername,peername,peernamelen);
  393.     up->peernamelen = peernamelen;
  394.  
  395.     /* Set up the local socket structures */
  396.     if(up->name == NULLCHAR){
  397.         switch(up->type){
  398.         case TYPE_TCP:
  399.         case TYPE_UDP:
  400.         case TYPE_RAW:
  401.             autobind(s,AF_INET);
  402.             break;
  403. #ifdef    AX25
  404.         case TYPE_AX25I:
  405.         case TYPE_AX25UI:
  406.             autobind(s,AF_AX25);
  407.             break;
  408. #endif
  409. #ifdef    NETROM
  410.         case TYPE_NETROML3:
  411.         case TYPE_NETROML4:
  412.             autobind(s,AF_NETROM);
  413.             break;
  414. #endif
  415.         }
  416.     }
  417.     switch(up->type){
  418.     case TYPE_TCP:
  419.         /* Construct the TCP-style ports from the sockaddr structs */
  420.         local.in = (struct sockaddr_in *)up->name;
  421.         remote.in = (struct sockaddr_in *)up->peername;
  422.  
  423.         if(local.in->sin_addr.s_addr == INADDR_ANY)
  424.             /* Choose a local address */
  425.             local.in->sin_addr.s_addr =
  426.              locaddr(remote.in->sin_addr.s_addr);
  427.  
  428.         lsock.address = local.in->sin_addr.s_addr;
  429.         lsock.port = local.in->sin_port;
  430.         fsock.address = remote.in->sin_addr.s_addr;
  431.         fsock.port = remote.in->sin_port;
  432.  
  433.         /* Open the TCB in active mode */
  434.         up->cb.tcb = open_tcp(&lsock,&fsock,TCP_ACTIVE,0,
  435.          s_trcall,s_ttcall,s_tscall,0,s);
  436.  
  437.         /* Wait for the connection to complete */
  438.         while((cb.tcb = up->cb.tcb) != NULLTCB && cb.tcb->state != TCP_ESTABLISHED){
  439.             if(up->noblock){
  440.                 errno = EWOULDBLOCK;
  441.                 return -1;
  442.             } else if((errno = pwait(up)) != 0){
  443.                 return -1;
  444.             }
  445.         }
  446.         if(cb.tcb == NULLTCB){
  447.             /* Probably got refused */
  448.             free(up->peername);
  449.             up->peername = NULLCHAR;
  450.             errno = ECONNREFUSED;
  451.             return -1;
  452.         }
  453.         break;
  454.     case TYPE_UDP:
  455. #ifdef    AX25
  456.     case TYPE_AX25UI:
  457. #endif
  458. #ifdef    NETROM
  459.     case TYPE_NETROML3:
  460. #endif
  461.     case TYPE_RAW:
  462.         /* Control block already created by bind() */
  463.         break;
  464. #ifdef    AX25
  465.     case TYPE_AX25I:
  466.         local.ax = (struct sockaddr_ax *)up->name;
  467.         remote.ax = (struct sockaddr_ax *)up->peername;
  468.         if((iface = if_lookup(remote.ax->iface)) == NULLIF){
  469.             errno = EINVAL;
  470.             return -1;
  471.         }
  472.         if(local.ax->ax25_addr[0] == '\0'){
  473.             /* The local address was unspecified; set it from
  474.              * the interface address
  475.              */
  476.             memcpy(local.ax->ax25_addr,iface->hwaddr,AXALEN);
  477.         }
  478.         /* If we already have an AX25 link we can use it */
  479.         if((up->cb.ax25 = find_ax25(remote.ax->ax25_addr)) != NULLAX25
  480.            && up->cb.ax25->state != LAPB_DISCONNECTED &&
  481.            up->cb.ax25->user == -1) {
  482.             up->cb.ax25->user = s;
  483.             up->cb.ax25->r_upcall = s_arcall;
  484.             up->cb.ax25->t_upcall = s_atcall;
  485.             up->cb.ax25->s_upcall = s_ascall;
  486.             if(up->cb.ax25->state == LAPB_CONNECTED
  487.                || up->cb.ax25->state == LAPB_RECOVERY)
  488.                     return 0;
  489.         } else
  490.             up->cb.ax25 = open_ax25(iface,local.ax->ax25_addr,
  491.              remote.ax->ax25_addr,AX_ACTIVE,
  492.              Axwindow,s_arcall,s_atcall,s_ascall,s);
  493.  
  494.         /* Wait for the connection to complete */
  495.         while((cb.ax25 = up->cb.ax25) != NULLAX25 && cb.ax25->state != LAPB_CONNECTED){
  496.             if(up->noblock){
  497.                 errno = EWOULDBLOCK;
  498.                 return -1;
  499.             } else if((errno = pwait(up)) != 0){
  500.                 return -1;
  501.             }
  502.         }
  503.         if(cb.ax25 == NULLAX25){
  504.             /* Connection probably already exists */
  505.             free(up->peername);
  506.             up->peername = NULLCHAR;
  507.             errno = ECONNREFUSED;
  508.             return -1;
  509.         }
  510.         break;
  511. #endif
  512. #ifdef    NETROM
  513.     case TYPE_NETROML4:
  514.         local.nr = (struct sockaddr_nr *)up->name;
  515.         remote.nr = (struct sockaddr_nr *)up->peername;
  516.         up->cb.nr4 = open_nr4(&local.nr->nr_addr,&remote.nr->nr_addr,
  517.          AX_ACTIVE,s_nrcall,s_ntcall,s_nscall,s);
  518.  
  519.         /* Wait for the connection to complete */
  520.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB && cb.nr4->state != NR4STCON){
  521.             if(up->noblock){
  522.                 errno = EWOULDBLOCK;
  523.                 return -1;
  524.             } else if((errno = pwait(up)) != 0){
  525.                 return -1;
  526.             }
  527.         }
  528.         if(cb.nr4 == NULLNR4CB){
  529.             /* Connection probably already exists */
  530.             free(up->peername);
  531.             up->peername = NULLCHAR;
  532.             errno = ECONNREFUSED;
  533.             return -1;
  534.         }
  535.         break;
  536. #endif
  537.     }
  538.     return 0;
  539. }
  540. /* Wait for a connection. Valid only for connection-oriented sockets. */
  541. int
  542. accept(s,peername,peernamelen)
  543. int s;            /* Socket index */
  544. char *peername;        /* Peer name */
  545. int *peernamelen;    /* Length of peer name */
  546. {
  547.     int i;
  548.     register struct usock *up;
  549.  
  550.     if((up = itop(s)) == NULLUSOCK){
  551.         errno = EBADF;
  552.         return -1;
  553.     }
  554.     if(up->type == TYPE_LOCAL_DGRAM || up->type == TYPE_LOCAL_STREAM){
  555.         errno = EINVAL;
  556.         return -1;
  557.     }
  558.     if(up->cb.p == NULLCHAR){
  559.         errno = EOPNOTSUPP;
  560.         return -1;
  561.     }
  562.     /* Accept is valid only for stream sockets */
  563.     switch(up->type){
  564.     case TYPE_TCP:
  565. #ifdef    AX25
  566.     case TYPE_AX25I:
  567. #endif
  568. #ifdef    NETROM
  569.     case TYPE_NETROML4:
  570. #endif
  571.         break;
  572.     default:
  573.         errno = EOPNOTSUPP;
  574.         return -1;
  575.     }    
  576.     /* Wait for the state-change upcall routine to signal us */
  577.     while(up->cb.p != NULLCHAR && up->rdysock == -1){
  578.         if(up->noblock){
  579.             errno = EWOULDBLOCK;
  580.             return -1;
  581.         } else if((errno = pwait(up)) != 0){
  582.             return -1;
  583.         }
  584.     }
  585.     if(up->cb.p == NULLCHAR){
  586.         /* Blown away */
  587.         errno = EBADF;
  588.         return -1;
  589.     }
  590.     i = up->rdysock;
  591.     up->rdysock = -1;
  592.  
  593.     up = itop(i);
  594.     if(peername != NULLCHAR && peernamelen != NULL){
  595.         *peernamelen = min(up->peernamelen,*peernamelen);
  596.         memcpy(peername,up->peername,*peernamelen);
  597.     }
  598.     return i;
  599. }
  600. /* Low-level receive routine. Passes mbuf back to user; more efficient than
  601.  * higher-level functions recv() and recvfrom(). Datagram sockets ignore
  602.  * the len parameter.
  603.  */
  604. int
  605. recv_mbuf(s,bpp,flags,from,fromlen)
  606. int s;            /* Socket index */
  607. struct mbuf **bpp;    /* Place to stash receive buffer */
  608. int flags;        /* Unused; will control out-of-band data, etc */
  609. char *from;        /* Peer address (only for datagrams) */
  610. int *fromlen;        /* Length of peer address */
  611. {
  612.     register struct usock *up;
  613.     int cnt;
  614.     union cb cb;
  615.     struct socket fsocket;
  616. #ifdef    NETROM
  617.     struct nr3hdr n3hdr;
  618. #endif
  619.     union sp remote;
  620.     struct ip ip;
  621.     struct mbuf *bp;
  622.  
  623.     if((up = itop(s)) == NULLUSOCK){
  624.         errno = EBADF;
  625.         return -1;
  626.     }
  627.     if(up->ibuf != NULLBUF){
  628.         /* Return input buffer */
  629.         cnt = len_p(up->ibuf);
  630.         if(bpp != NULLBUFP)
  631.             *bpp = up->ibuf;
  632.         else
  633.             free_p(up->ibuf);
  634.         up->ibuf = NULLBUF;        
  635.         return cnt;
  636.     }
  637.     switch(up->type){
  638.     case TYPE_LOCAL_STREAM:
  639.     case TYPE_LOCAL_DGRAM:
  640.         while(up->cb.local != NULLLOC && up->cb.local->q == NULLBUF
  641.               && up->cb.local->peer != NULLUSOCK){
  642.             if(up->noblock){
  643.                 errno = EWOULDBLOCK;
  644.                 return -1;
  645.             } else if((errno = pwait(up)) != 0){
  646.                 return -1;
  647.             }
  648.         }
  649.         if(up->cb.local == NULLLOC){
  650.             errno = EBADF;
  651.             return -1;
  652.         }
  653.         if(up->cb.local->q == NULLBUF &&
  654.            up->cb.local->peer == NULLUSOCK){
  655.             errno = ENOTCONN;
  656.             return -1;
  657.         }
  658.         /* For datagram sockets, this will return the
  659.          * first packet on the queue. For stream sockets,
  660.          * this will return everything.
  661.          */
  662.         bp = dequeue(&up->cb.local->q);
  663.         if(up->cb.local->q == NULLBUF
  664.          && (up->cb.local->flags & LOC_SHUTDOWN))
  665.             close_s(s);
  666.         psignal(up,0);
  667.         cnt = len_p(bp);
  668.         break;
  669.     case TYPE_TCP:
  670.         while((cb.tcb = up->cb.tcb) != NULLTCB
  671.          && cb.tcb->r_upcall != trdiscard
  672.                  && (cnt = recv_tcp(cb.tcb,&bp,(int16)0)) == -1){
  673.             if(up->noblock){
  674.                 errno = EWOULDBLOCK;
  675.                 return -1;
  676.             } else if((errno = pwait(up)) != 0){
  677.                 return -1;
  678.             }
  679.         }
  680.         if(cb.tcb == NULLTCB){
  681.             /* Connection went away */
  682.             errno = ENOTCONN;
  683.             return -1;
  684.         } else if(cb.tcb->r_upcall == trdiscard){
  685.             /* Receive shutdown has been done */
  686.             errno = ENOTCONN;    /* CHANGE */
  687.             return -1;
  688.         }
  689.         break;
  690.     case TYPE_UDP:
  691.         while((cb.udp = up->cb.udp) != NULLUDP
  692.         && (cnt = recv_udp(cb.udp,&fsocket,&bp)) == -1){
  693.             if(up->noblock){
  694.                 errno = EWOULDBLOCK;
  695.                 return -1;
  696.             } else if((errno = pwait(up)) != 0){
  697.                 return -1;
  698.             }
  699.         }
  700.         if(cb.udp == NULLUDP){
  701.             /* Connection went away */
  702.             errno = ENOTCONN;
  703.             return -1;
  704.         }
  705.         if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  706.             remote.in = (struct sockaddr_in *)from;
  707.             remote.in->sin_family = AF_INET;
  708.             remote.in->sin_addr.s_addr = fsocket.address;
  709.             remote.in->sin_port = fsocket.port;
  710.             *fromlen = SOCKSIZE;
  711.         }
  712.         break;
  713.     case TYPE_RAW:
  714.         while((cb.rip = up->cb.rip) != NULLRIP
  715.          && cb.rip->rcvq == NULLBUF){
  716.             if(up->noblock){
  717.                 errno = EWOULDBLOCK;
  718.                 return -1;
  719.             } else if((errno = pwait(up)) != 0){
  720.                 return -1;
  721.             }
  722.         }
  723.         if(cb.rip == NULLRIP){
  724.             /* Connection went away */
  725.             errno = ENOTCONN;
  726.             return -1;
  727.         }
  728.         bp = dequeue(&cb.rip->rcvq);
  729.         ntohip(&ip,&bp);
  730.  
  731.         cnt = len_p(bp);
  732.         if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  733.             remote.in = (struct sockaddr_in *)from;
  734.             remote.in->sin_family = AF_INET;
  735.             remote.in->sin_addr.s_addr = ip.source;
  736.             remote.in->sin_port = 0;
  737.             *fromlen = SOCKSIZE;
  738.         }
  739.         break;
  740. #ifdef    AX25
  741.     case TYPE_AX25I:
  742.         while((cb.ax25 = up->cb.ax25) != NULLAX25
  743.          && (bp = recv_ax25(cb.ax25,(int16)0)) == NULLBUF){
  744.             if(up->noblock){
  745.                 errno = EWOULDBLOCK;
  746.                 return -1;
  747.             } else if((errno = pwait(up)) != 0){
  748.                 return -1;
  749.             }
  750.         }
  751.         if(cb.ax25 == NULLAX25){
  752.             /* Connection went away */
  753.             errno = ENOTCONN;
  754.             return -1;
  755.         }
  756.         cnt = bp->cnt;
  757.         break;
  758.     case TYPE_AX25UI:
  759.         while(s == Axui_sock && Bcq == NULLBUF){
  760.             if(up->noblock){
  761.                 errno = EWOULDBLOCK;
  762.                 return -1;
  763.             } else if((errno = pwait(&Bcq)) != 0){
  764.                 return -1;
  765.             }
  766.         }
  767.         if(s != Axui_sock){
  768.             errno = ENOTCONN;
  769.             return -1;
  770.         }
  771.         bp = dequeue(&Bcq);
  772.  
  773.         if(from != NULLCHAR && fromlen != NULLINT
  774.            && *fromlen >= sizeof(struct sockaddr_ax)){
  775.             pullup(&bp,from,sizeof(struct sockaddr_ax));
  776.             *fromlen = sizeof(struct sockaddr_ax);
  777.         } else {
  778.             pullup(&bp,NULLCHAR,sizeof(struct sockaddr_ax));
  779.         }
  780.         cnt = len_p(bp);
  781.         break;
  782. #endif
  783. #ifdef NETROM
  784.     case TYPE_NETROML3:
  785.         while((cb.rnr = up->cb.rnr) != NULLRNR
  786.          && cb.rnr->rcvq == NULLBUF){
  787.             if(up->noblock){
  788.                 errno = EWOULDBLOCK;
  789.                 return -1;
  790.             } else if((errno = pwait(up)) != 0){
  791.                 return -1;
  792.             }
  793.         }
  794.         if(cb.rnr == NULLRNR){
  795.             /* Connection went away */
  796.             errno = ENOTCONN;
  797.             return -1;
  798.         }
  799.         bp = dequeue(&cb.rnr->rcvq);
  800.         ntohnr3(&n3hdr,&bp);
  801.         cnt = len_p(bp);
  802.         if(from != NULLCHAR && fromlen != NULLINT
  803.            && *fromlen >= sizeof(struct sockaddr_nr)){
  804.             remote.nr = (struct sockaddr_nr *)from;
  805.             remote.nr->nr_family = AF_NETROM;
  806.             /* The callsign of the local user is not part of
  807.                NET/ROM level 3, so that field is not used here */
  808.             memcpy(remote.nr->nr_addr.node,n3hdr.source,AXALEN);
  809.             *fromlen = sizeof(struct sockaddr_nr);
  810.         }
  811.         break;
  812.     case TYPE_NETROML4:
  813.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB
  814.          && (bp = recv_nr4(cb.nr4,(int16)0)) == NULLBUF){
  815.             if(up->noblock){
  816.                 errno = EWOULDBLOCK;
  817.                 return -1;
  818.             } else if((errno = pwait(up)) != 0){
  819.                 return -1;
  820.             }
  821.         }
  822.         if(cb.nr4 == NULLNR4CB){
  823.             /* Connection went away */
  824.             errno = ENOTCONN;
  825.             return -1;
  826.         }
  827.         cnt = bp->cnt;
  828.         break;
  829. #endif
  830.     }
  831.     if(bpp != NULLBUFP)
  832.         *bpp = bp;
  833.     else
  834.         free_p(bp);
  835.     return cnt;
  836. }
  837. /* Low level send routine; user supplies mbuf for transmission. More
  838.  * efficient than send() or sendto(), the higher level interfaces.
  839.  * The "to" and "tolen" parameters are ignored on connection-oriented
  840.  * sockets.
  841.  *
  842.  * In case of error, bp is freed so the caller doesn't have to worry about it.
  843.  */
  844. int
  845. send_mbuf(s,bp,flags,to,tolen)
  846. int s;            /* Socket index */
  847. struct mbuf *bp;    /* Buffer to send */
  848. int flags;        /* not currently used */
  849. char *to;        /* Destination, only for datagrams */
  850. int tolen;        /* Length of destination */
  851. {
  852.     register struct usock *up;
  853.     union cb cb;
  854.     union sp local,remote;
  855.     struct socket lsock,fsock;
  856.     int cnt;
  857.  
  858.     if((up = itop(s)) == NULLUSOCK){
  859.         free_p(bp);
  860.         errno = EBADF;
  861.         return -1;
  862.     }
  863. #ifndef    notdef
  864.     if(up->obuf != NULLBUF){
  865.         /* If there's unflushed output, send it.
  866.          * Note the importance of clearing up->obuf
  867.          * before the recursive call!
  868.          */
  869.         struct mbuf *bp1;
  870.  
  871.         bp1 = up->obuf;
  872.         up->obuf = NULLBUF;
  873.         send_mbuf(s,bp1,flags,to,tolen);
  874.     }
  875. #endif
  876.     if(up->name == NULLCHAR){
  877.         /* Automatic local name assignment for datagram sockets */
  878.         switch(up->type){
  879.         case TYPE_LOCAL_STREAM:
  880.         case TYPE_LOCAL_DGRAM:
  881.             break;    /* no op */
  882.         case TYPE_UDP:
  883.         case TYPE_RAW:
  884.             autobind(s,AF_INET);
  885.             break;
  886. #ifdef    AX25
  887.         case TYPE_AX25UI:
  888.             autobind(s,AF_AX25);
  889.             break;
  890. #endif
  891. #ifdef    NETROM
  892.         case TYPE_NETROML3:
  893.         case TYPE_NETROML4:
  894.             autobind(s,AF_NETROM);
  895.             break;
  896. #endif
  897.         default:
  898.             free_p(bp);
  899.             errno = ENOTCONN;
  900.             return -1;
  901.         }
  902.     }
  903.     cnt = len_p(bp);
  904.     switch(up->type){
  905.     case TYPE_LOCAL_DGRAM:
  906.         if(up->cb.local->peer == NULLUSOCK){
  907.             free_p(bp);
  908.             errno = ENOTCONN;
  909.             return -1;
  910.         }
  911.         enqueue(&up->cb.local->peer->cb.local->q,bp);
  912.         psignal(up->cb.local->peer,0);
  913.         /* If high water mark has been reached, block */
  914.         while(up->cb.local->peer != NULLUSOCK &&
  915.               len_q(up->cb.local->peer->cb.local->q) >=
  916.               up->cb.local->peer->cb.local->hiwat){
  917.             if(up->noblock){
  918.                 errno = EWOULDBLOCK;
  919.                 return -1;
  920.             } else if((errno = pwait(up->cb.local->peer)) != 0){
  921.                 return -1;
  922.             }
  923.         }
  924.         if(up->cb.local->peer == NULLUSOCK){
  925.             errno = ENOTCONN;
  926.             return -1;
  927.         }
  928.         break;
  929.     case TYPE_LOCAL_STREAM:
  930.         if(up->cb.local->peer == NULLUSOCK){
  931.             free_p(bp);
  932.             errno = ENOTCONN;
  933.             return -1;
  934.         }
  935.         append(&up->cb.local->peer->cb.local->q,bp);
  936.         psignal(up->cb.local->peer,0);
  937.         /* If high water mark has been reached, block */
  938.         while(up->cb.local->peer != NULLUSOCK &&
  939.               len_p(up->cb.local->peer->cb.local->q) >=
  940.               up->cb.local->peer->cb.local->hiwat){
  941.             if(up->noblock){
  942.                 errno = EWOULDBLOCK;
  943.                 return -1;
  944.             } else if((errno = pwait(up->cb.local->peer)) != 0){
  945.                 return -1;
  946.             }
  947.         }
  948.         if(up->cb.local->peer == NULLUSOCK){
  949.             errno = ENOTCONN;
  950.             return -1;
  951.         }
  952.         break;
  953.     case TYPE_TCP:
  954.         if((cb.tcb = up->cb.tcb) == NULLTCB){
  955.             free_p(bp);
  956.             errno = ENOTCONN;
  957.             return -1;
  958.         }        
  959.         cnt = send_tcp(cb.tcb,bp);
  960.  
  961.         while((cb.tcb = up->cb.tcb) != NULLTCB &&
  962.          cb.tcb->sndcnt > cb.tcb->window){
  963.             /* Send queue is full */
  964.             if(up->noblock){
  965.                 errno = EWOULDBLOCK;
  966.                 return -1;
  967.             } else if((errno = pwait(up)) != 0){
  968.                 return -1;
  969.             }
  970.         }
  971.          if(cb.tcb == NULLTCB){
  972.             errno = ENOTCONN;
  973.             return -1;
  974.         }
  975.         break;
  976.     case TYPE_UDP:
  977.         local.in = (struct sockaddr_in *)up->name;
  978.         lsock.address = local.in->sin_addr.s_addr;
  979.         lsock.port = local.in->sin_port;
  980.         if(to != NULLCHAR)
  981.             remote.in = (struct sockaddr_in *)to;
  982.         else if(up->peername != NULLCHAR)
  983.             remote.in = (struct sockaddr_in *)up->peername;
  984.         else {
  985.             errno = ENOTCONN;
  986.             return -1;
  987.         }    
  988.         fsock.address = remote.in->sin_addr.s_addr;
  989.         fsock.port = remote.in->sin_port;
  990.         send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  991.         break;
  992.     case TYPE_RAW:
  993.         local.in = (struct sockaddr_in *)up->name;
  994.         if(to != NULLCHAR)
  995.             remote.in = (struct sockaddr_in *)to;
  996.         else if(up->peername != NULLCHAR)
  997.             remote.in = (struct sockaddr_in *)up->peername;
  998.         else {
  999.             errno = ENOTCONN;
  1000.             return -1;
  1001.         }    
  1002.         ip_send(local.in->sin_addr.s_addr,remote.in->sin_addr.s_addr,
  1003.             (char)up->cb.rip->protocol,0,0,bp,0,0,0);
  1004.         break;
  1005. #ifdef    AX25
  1006.     case TYPE_AX25I:
  1007.         if((cb.ax25 = up->cb.ax25) == NULLAX25){
  1008.             free_p(bp);
  1009.             errno = ENOTCONN;
  1010.             return -1;
  1011.         }
  1012.         send_ax25(cb.ax25,bp,PID_NO_L3);
  1013.  
  1014.         while((cb.ax25 = up->cb.ax25) != NULLAX25 &&
  1015.          len_q(cb.ax25->txq) * cb.ax25->paclen > cb.ax25->window){
  1016.             if(up->noblock){
  1017.                 errno = EWOULDBLOCK;
  1018.                 return -1;
  1019.             } else if((errno = pwait(up)) != 0){
  1020.                 return -1;
  1021.             }
  1022.         }
  1023.         if(cb.ax25 == NULLAX25){
  1024.             errno = EBADF;
  1025.             return -1;
  1026.         }
  1027.         break;
  1028.     case TYPE_AX25UI:
  1029.         local.ax = (struct sockaddr_ax *)up->name;
  1030.         if(to != NULLCHAR)
  1031.             remote.ax = (struct sockaddr_ax *)to;
  1032.         else if(up->peername != NULLCHAR)
  1033.             remote.ax = (struct sockaddr_ax *)up->peername;
  1034.         else {
  1035.             errno = ENOTCONN;
  1036.             return -1;
  1037.         }
  1038.         ax_output(if_lookup(remote.ax->iface),
  1039.               remote.ax->ax25_addr,
  1040.               local.ax->ax25_addr,PID_NO_L3,bp);
  1041.         break;
  1042. #endif
  1043. #ifdef NETROM
  1044.     case TYPE_NETROML3:
  1045.         if(len_p(bp) > NR4MAXINFO) {
  1046.             free_p(bp);
  1047.             errno = EMSGSIZE;
  1048.             return -1;
  1049.         }
  1050.         local.nr = (struct sockaddr_nr *)up->name;
  1051.         if(to != NULLCHAR)
  1052.             remote.nr = (struct sockaddr_nr *)to;
  1053.         else if(up->peername != NULLCHAR)
  1054.             remote.nr = (struct sockaddr_nr *)up->peername;
  1055.         else {
  1056.             errno = ENOTCONN;
  1057.             return -1;
  1058.         }    
  1059.         /* The NETROM username is always ignored in outgoing traffic */
  1060.         nr_sendraw(remote.nr->nr_addr.node,
  1061.          up->cb.rnr->protocol,up->cb.rnr->protocol,bp);
  1062.         break;
  1063.     case TYPE_NETROML4:
  1064.         if((cb.nr4 = up->cb.nr4) == NULLNR4CB) {
  1065.             free_p(bp);
  1066.             errno = ENOTCONN;
  1067.             return -1;
  1068.         }
  1069.         if(len_p(bp) > NR4MAXINFO){ /* reject big packets */
  1070.             free_p(bp);
  1071.             errno = EMSGSIZE;
  1072.             return -1;
  1073.         }
  1074.         send_nr4(cb.nr4,bp);
  1075.  
  1076.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB &&
  1077.          cb.nr4->nbuffered >= cb.nr4->window){
  1078.             if(up->noblock){
  1079.                 errno = EWOULDBLOCK;
  1080.                 return -1;
  1081.             } else if((errno = pwait(up)) != 0){
  1082.                 errno = EINTR;
  1083.                 return -1;
  1084.             }
  1085.         }
  1086.         if(cb.nr4 == NULLNR4CB){
  1087.             errno = EBADF;
  1088.             return -1;
  1089.         }
  1090.         break;
  1091. #endif
  1092.     }    
  1093.     return cnt;
  1094. }
  1095. /* Return local name passed in an earlier bind() call */
  1096. int
  1097. getsockname(s,name,namelen)
  1098. int s;        /* Socket index */
  1099. char *name;    /* Place to stash name */
  1100. int *namelen;    /* Length of same */
  1101. {
  1102.     register struct usock *up;
  1103.  
  1104.     if((up = itop(s)) == NULLUSOCK){
  1105.         errno = EBADF;
  1106.         return -1;
  1107.     }
  1108.     if(name == NULLCHAR || namelen == (int *)NULL){
  1109.         errno = EFAULT;
  1110.         return -1;
  1111.     }
  1112.     if(up->name == NULLCHAR){
  1113.         /* Not bound yet */
  1114.         *namelen = 0;
  1115.         return 0;
  1116.     }
  1117.     if(up->name != NULLCHAR){
  1118.         *namelen = min(*namelen,up->namelen);
  1119.         memcpy(name,up->name,*namelen);
  1120.     }
  1121.     return 0;
  1122. }
  1123. /* Get remote name, returning result of earlier connect() call. */
  1124. int
  1125. getpeername(s,peername,peernamelen)
  1126. int s;            /* Socket index */
  1127. char *peername;        /* Place to stash name */
  1128. int *peernamelen;    /* Length of same */
  1129. {
  1130.     register struct usock *up;
  1131.  
  1132.     if((up = itop(s)) == NULLUSOCK){
  1133.         errno = EBADF;
  1134.         return -1;
  1135.     }
  1136.     if(up->peername == NULLCHAR){
  1137.         errno = ENOTCONN;
  1138.         return -1;
  1139.     }
  1140.     if(peername == NULLCHAR || peernamelen == (int *)NULL){
  1141.         errno = EFAULT;
  1142.         return -1;
  1143.     }
  1144.     *peernamelen = min(*peernamelen,up->peernamelen);
  1145.     memcpy(peername,up->peername,*peernamelen);
  1146.     return 0;
  1147. }
  1148. /* Return length of protocol queue, either send or receive. */
  1149. int
  1150. socklen(s,rtx)
  1151. int s;        /* Socket index */
  1152. int rtx;    /* 0 = receive queue, 1 = transmit queue */
  1153. {
  1154.     register struct usock *up;
  1155.     int len = -1;
  1156.  
  1157.     if((up = itop(s)) == NULLUSOCK){
  1158.         errno = EBADF;
  1159.         return -1;
  1160.     }
  1161.     if(up->cb.p == NULLCHAR){
  1162.         errno = ENOTCONN;
  1163.         return -1;
  1164.     }
  1165.     if(rtx < 0 || rtx > 1){
  1166.         errno = EINVAL;
  1167.         return -1;
  1168.     }
  1169.     switch(up->type){
  1170.     case TYPE_LOCAL_DGRAM:
  1171.         switch(rtx){
  1172.         case 0:
  1173.             len = len_q(up->cb.local->q);
  1174.             break;
  1175.         case 1:
  1176.             if(up->cb.local->peer != NULLUSOCK)
  1177.                 len = len_q(up->cb.local->peer->cb.local->q);
  1178.             break;
  1179.         }
  1180.         break;
  1181.     case TYPE_LOCAL_STREAM:
  1182.         switch(rtx){
  1183.         case 0:
  1184.             len = len_p(up->cb.local->q) + len_p(up->ibuf);
  1185.             break;
  1186.         case 1:
  1187.             if(up->cb.local->peer != NULLUSOCK)
  1188.                 len = len_p(up->cb.local->peer->cb.local->q)
  1189.                       + len_p(up->obuf);
  1190.             break;
  1191.         }
  1192.         break;
  1193.     case TYPE_TCP:
  1194.         switch(rtx){
  1195.         case 0:
  1196.             len = up->cb.tcb->rcvcnt + len_p(up->ibuf);
  1197.             break;
  1198.         case 1:
  1199.             len = up->cb.tcb->sndcnt + len_p(up->obuf);
  1200.             break;
  1201.         }
  1202.         break;
  1203.     case TYPE_UDP:
  1204.         switch(rtx){
  1205.         case 0:
  1206.             len = up->cb.udp->rcvcnt;
  1207.             break;
  1208.         case 1:
  1209.             len = 0;
  1210.             break;
  1211.         }
  1212.         break;
  1213. #ifdef    AX25
  1214.     case TYPE_AX25I:
  1215.         switch(rtx){
  1216.         case 0:
  1217.             len = len_p(up->cb.ax25->rxq) + len_p(up->ibuf);
  1218.             break;
  1219.         case 1:    /* Number of packets, not bytes */
  1220.             len = len_q(up->cb.ax25->txq);
  1221.             if(up->obuf != NULLBUF)
  1222.                 len++;
  1223.         }
  1224.         break;
  1225.     case TYPE_AX25UI:
  1226.         switch(rtx){    
  1227.         case 0:
  1228.             len = len_q(Bcq);
  1229.             break;
  1230.         case 1:
  1231.             len = 0;        
  1232.             break;
  1233.         }
  1234.         break;
  1235. #endif
  1236. #ifdef NETROM
  1237.     case TYPE_NETROML3:
  1238.         switch(rtx){    
  1239.         case 0:
  1240.             len = len_q(up->cb.rnr->rcvq);
  1241.             break;
  1242.         case 1:
  1243.             len = 0;        
  1244.         }
  1245.         break;
  1246.     case TYPE_NETROML4:
  1247.         switch(rtx){
  1248.         case 0:
  1249.             len = len_p(up->cb.nr4->rxq) + len_p(up->obuf);
  1250.             break;
  1251.         case 1:    /* Number of packets, not bytes */
  1252.             len = len_q(up->cb.nr4->txq);
  1253.             if(up->obuf != NULLBUF)
  1254.                 len++;
  1255.             break;
  1256.         }
  1257.         break;
  1258. #endif
  1259.     case TYPE_RAW:
  1260.         switch(rtx){    
  1261.         case 0:
  1262.             len = len_q(up->cb.rip->rcvq);
  1263.             break;
  1264.         case 1:
  1265.             len = 0;        
  1266.             break;
  1267.         }
  1268.         break;
  1269.     }
  1270.     return len;
  1271. }
  1272. /* Force retransmission. Valid only for connection-oriented sockets. */
  1273. int
  1274. sockkick(s)
  1275. int s;    /* Socket index */
  1276. {
  1277.     register struct usock *up;
  1278.  
  1279.     if((up = itop(s)) == NULLUSOCK){
  1280.         errno = EBADF;
  1281.         return -1;
  1282.     }
  1283.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  1284.         errno = EINVAL;
  1285.         return -1;
  1286.     }
  1287.     if(up->cb.p == NULLCHAR){
  1288.         errno = ENOTCONN;
  1289.         return -1;
  1290.     }
  1291.     switch(up->type){
  1292.     case TYPE_TCP:
  1293.         kick_tcp(up->cb.tcb);
  1294.         break;
  1295. #ifdef    AX25
  1296.     case TYPE_AX25I:
  1297.         kick_ax25(up->cb.ax25);
  1298.         break;
  1299. #endif
  1300. #ifdef NETROM
  1301.     case TYPE_NETROML4:
  1302.         kick_nr4(up->cb.nr4);
  1303.         break;
  1304. #endif
  1305.     default:
  1306.         /* Datagram sockets can't be kicked */
  1307.         errno = EOPNOTSUPP;
  1308.         return -1;
  1309.     }
  1310.     return 0;
  1311. }
  1312.  
  1313. /* Change owner of socket, return previous owner */
  1314. struct proc *
  1315. sockowner(s,newowner)
  1316. int s;            /* Socket index */
  1317. struct proc *newowner;    /* Process table address of new owner */
  1318. {
  1319.     register struct usock *up;
  1320.     struct proc *pp;
  1321.  
  1322.     if((up = itop(s)) == NULLUSOCK){
  1323.         errno = EBADF;
  1324.         return NULLPROC;
  1325.     }
  1326.     pp = up->owner;
  1327.     if(newowner != NULLPROC)
  1328.         up->owner = newowner;
  1329.     return pp;
  1330. }
  1331. /* Close down a socket three ways. Type 0 means "no more receives"; this
  1332.  * replaces the incoming data upcall with a routine that discards further
  1333.  * data. Type 1 means "no more sends", and obviously corresponds to sending
  1334.  * a TCP FIN. Type 2 means "no more receives or sends". This I interpret
  1335.  * as "abort the connection".
  1336.  */
  1337. int
  1338. shutdown(s,how)
  1339. int s;        /* Socket index */
  1340. int how;    /* (see above) */
  1341. {
  1342.     register struct usock *up;
  1343.  
  1344.     if((up = itop(s)) == NULLUSOCK){
  1345.         errno = EBADF;
  1346.         return -1;
  1347.     }
  1348.     if(up->cb.p == NULLCHAR){
  1349.         errno = ENOTCONN;
  1350.         return -1;
  1351.     }
  1352.     switch(up->type){
  1353.     case TYPE_LOCAL_DGRAM:
  1354.     case TYPE_LOCAL_STREAM:
  1355.         if(up->cb.local->q == NULLBUF)
  1356.             close_s(s);
  1357.         else
  1358.             up->cb.local->flags = LOC_SHUTDOWN;
  1359.         break;
  1360.     case TYPE_TCP:
  1361.         switch(how){
  1362.         case 0:    /* No more receives -- replace upcall */
  1363.             up->cb.tcb->r_upcall = trdiscard;
  1364.             break;
  1365.         case 1:    /* Send EOF */
  1366.             close_tcp(up->cb.tcb);
  1367.             break;
  1368.         case 2:    /* Blow away TCB */
  1369.             reset_tcp(up->cb.tcb);
  1370.             up->cb.tcb = NULLTCB;
  1371.             break;
  1372.         }
  1373.         break;
  1374. #ifdef    AX25
  1375.     case TYPE_AX25UI:
  1376.         close_s(s);
  1377.         break;
  1378.     case TYPE_AX25I:
  1379.         switch(how){
  1380.         case 0:
  1381.         case 1:    /* Attempt regular disconnect */
  1382.             disc_ax25(up->cb.ax25);
  1383.             break;
  1384.         case 2: /* Blow it away */
  1385.             reset_ax25(up->cb.ax25);
  1386.             up->cb.ax25 = NULLAX25;
  1387.             break;
  1388.         }
  1389.         break;        
  1390. #endif
  1391. #ifdef    NETROM
  1392.     case TYPE_NETROML3:
  1393.         close_s(s);
  1394.         break;
  1395.     case TYPE_NETROML4:
  1396.         switch(how){
  1397.         case 0:
  1398.         case 1:    /* Attempt regular disconnect */
  1399.             disc_nr4(up->cb.nr4);
  1400.             break;
  1401.         case 2: /* Blow it away */
  1402.             reset_nr4(up->cb.nr4);
  1403.             up->cb.nr4 = NULLNR4CB;
  1404.             break;
  1405.         }
  1406.         break;        
  1407. #endif
  1408.     case TYPE_RAW:
  1409.     case TYPE_UDP:
  1410.         close_s(s);
  1411.         break;
  1412.     default:
  1413.         errno = EOPNOTSUPP;
  1414.         return -1;
  1415.     }
  1416.     psignal(up,0);
  1417.     return 0;
  1418. }
  1419. /* Close a socket, freeing it for reuse. Try to do a graceful close on a
  1420.  * TCP socket, if possible
  1421.  */
  1422. int
  1423. close_s(s)
  1424. int s;        /* Socket index */
  1425. {
  1426.     register struct usock *up;
  1427.  
  1428.     if((up = itop(s)) == NULLUSOCK){
  1429.         errno = EBADF;
  1430.         return -1;
  1431.     }
  1432.     if(--up->refcnt > 0)
  1433.         return 0;    /* Others are still using it */
  1434.     usflush(s);
  1435.     if(up->ibuf != NULLBUF){
  1436.         free_p(up->ibuf);
  1437.         up->ibuf = NULLBUF;
  1438.     }
  1439.     switch(up->type){
  1440.     case TYPE_LOCAL_STREAM:
  1441.     case TYPE_LOCAL_DGRAM:
  1442.         if(up->cb.local->peer != NULLUSOCK){
  1443.             up->cb.local->peer->cb.local->peer = NULLUSOCK;
  1444.             psignal(up->cb.local->peer,0);
  1445.         }
  1446.         free_q(&up->cb.local->q);
  1447.         free(up->cb.local);
  1448.         break;
  1449.     case TYPE_TCP:
  1450.         if(up->cb.tcb != NULLTCB){    /* In case it's been reset */
  1451.             up->cb.tcb->r_upcall = trdiscard;
  1452.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1453.             up->cb.tcb->user = -1;
  1454.             close_tcp(up->cb.tcb);
  1455.         }
  1456.         break;
  1457.     case TYPE_UDP:
  1458.         if(up->cb.udp != NULLUDP){
  1459.             del_udp(up->cb.udp);
  1460.         }
  1461.         break;
  1462. #ifdef    AX25
  1463.     case TYPE_AX25I:
  1464.         if(up->cb.ax25 != NULLAX25){
  1465.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1466.             up->cb.ax25->user = -1;
  1467.             disc_ax25(up->cb.ax25);
  1468.         }
  1469.         break;
  1470.     case TYPE_AX25UI:
  1471.         Axui_sock = -1;
  1472.         free_q(&Bcq);
  1473.         psignal(&Bcq,0);    /* Unblock any reads */
  1474.         break;
  1475. #endif
  1476. #ifdef    NETROM
  1477.     case TYPE_NETROML3:
  1478.         del_rnr(up->cb.rnr);
  1479.         break;
  1480.     case TYPE_NETROML4:
  1481.         if(up->cb.nr4 != NULLNR4CB){
  1482.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1483.             up->cb.nr4->user = -1;
  1484.             disc_nr4(up->cb.nr4);
  1485.         }
  1486.         break;
  1487. #endif
  1488.     case TYPE_RAW:
  1489.         del_ip(up->cb.rip);
  1490.         break;
  1491.     default:
  1492.         errno = EOPNOTSUPP;
  1493.         return -1;
  1494.     }
  1495. #ifdef    LZW
  1496.     if(up->zout != NULLLZW || up->zin != NULLLZW)
  1497.         lzwfree(up);
  1498. #endif
  1499.     free(up->name);
  1500.     free(up->peername);
  1501.  
  1502.     up->cb.p = NULLCHAR;
  1503.     up->name = up->peername = NULLCHAR;
  1504.     up->type = NOTUSED;
  1505.     psignal(up,0);    /* Wake up anybody doing an accept() or recv() */
  1506.     return 0;
  1507. }
  1508. /* Increment reference count for specified socket */
  1509. int
  1510. usesock(s)
  1511. int s;
  1512. {
  1513.     struct usock *up;
  1514.  
  1515.     if((up = itop(s)) == NULLUSOCK){
  1516.         errno = EBADF;
  1517.         return -1;
  1518.     }
  1519.     up->refcnt++;
  1520.     return 0;
  1521. }
  1522. /* Blow away all sockets belonging to a certain process. Used by killproc(). */
  1523. void
  1524. freesock(pp)
  1525. struct proc *pp;
  1526. {
  1527.     register struct usock *up;
  1528.     register int i;
  1529.  
  1530.     for(i=SOCKBASE;i < Nusock+SOCKBASE;i++){
  1531.         up = itop(i);
  1532.         if(up != NULLUSOCK && up->type != NOTUSED && up->owner == pp)
  1533.             shutdown(i,2);
  1534.     }
  1535. }
  1536. /* Start of internal subroutines */
  1537.  
  1538. /* Raw IP receive upcall routine */
  1539. static void
  1540. rip_recv(rp)
  1541. struct raw_ip *rp;
  1542. {
  1543.     psignal(itop(rp->user),1);
  1544.     pwait(NULL);
  1545. }
  1546.  
  1547. /* UDP receive upcall routine */
  1548. static void
  1549. s_urcall(iface,udp,cnt)
  1550. struct iface *iface;
  1551. struct udp_cb *udp;
  1552. int cnt;
  1553. {
  1554.     psignal(itop(udp->user),1);
  1555.     pwait(NULL);
  1556. }
  1557. /* TCP receive upcall routine */
  1558. static void
  1559. s_trcall(tcb,cnt)
  1560. struct tcb *tcb;
  1561. int cnt;
  1562. {
  1563.     /* Wake up anybody waiting for data, and let them run */
  1564.     psignal(itop(tcb->user),1);
  1565.     pwait(NULL);
  1566. }
  1567. /* TCP transmit upcall routine */
  1568. static void
  1569. s_ttcall(tcb,cnt)
  1570. struct tcb *tcb;
  1571. int cnt;
  1572. {
  1573.     /* Wake up anybody waiting to send data, and let them run */
  1574.     psignal(itop(tcb->user),1);
  1575.     pwait(NULL);
  1576. }
  1577. /* TCP state change upcall routine */
  1578. static void
  1579. s_tscall(tcb,old,new)
  1580. struct tcb *tcb;
  1581. int old,new;
  1582. {
  1583.     int s,ns;
  1584.     struct usock *up,*nup,*oup;
  1585.     union sp sp;
  1586.  
  1587.     s = tcb->user;
  1588.     oup = up = itop(s);
  1589.  
  1590.     switch(new){
  1591.     case TCP_CLOSED:
  1592.         /* Clean up. If the user has already closed the socket,
  1593.          * then up will be null (s was set to -1 by the close routine).
  1594.          * If not, then this is an abnormal close (e.g., a reset)
  1595.          * and clearing out the pointer in the socket structure will
  1596.          * prevent any further operations on what will be a freed
  1597.          * control block. Also wake up anybody waiting on events
  1598.          * related to this tcb so they will notice it disappearing.
  1599.          */
  1600.         if(up != NULLUSOCK){
  1601.             up->cb.tcb = NULLTCB;
  1602.             up->errcodes[0] = tcb->reason;
  1603.             up->errcodes[1] = tcb->type;
  1604.             up->errcodes[2] = tcb->code;
  1605.         }
  1606.         del_tcp(tcb);
  1607.         break;
  1608.     case TCP_SYN_RECEIVED:
  1609.         /* Handle an incoming connection. If this is a server TCB,
  1610.          * then we're being handed a "clone" TCB and we need to
  1611.          * create a new socket structure for it. In either case,
  1612.          * find out who we're talking to and wake up the guy waiting
  1613.          * for the connection.
  1614.          */
  1615.         if(tcb->flags.clone){
  1616.             /* Clone the socket */
  1617.             ns = socket(AF_INET,SOCK_STREAM,0);
  1618.             nup = itop(ns);
  1619.             ASSIGN(*nup,*up);
  1620.             tcb->user = ns;
  1621.             nup->cb.tcb = tcb;
  1622.             /* Allocate new memory for the name areas */
  1623.             nup->name = mallocw(SOCKSIZE);
  1624.             nup->peername = mallocw(SOCKSIZE);
  1625.             /* Store the new socket # in the old one */
  1626.             up->rdysock = ns;
  1627.             up = nup;
  1628.             s = ns;
  1629.         } else {
  1630.             /* Allocate space for the peer's name */
  1631.             up->peername = mallocw(SOCKSIZE);
  1632.             /* Store the old socket # in the old socket */
  1633.             up->rdysock = s;
  1634.         }
  1635.         /* Load the addresses. Memory for the name has already
  1636.          * been allocated, either above or in the original bind.
  1637.          */
  1638.         sp.p = up->name;
  1639.         sp.in->sin_family = AF_INET;
  1640.         sp.in->sin_addr.s_addr = up->cb.tcb->conn.local.address;
  1641.         sp.in->sin_port = up->cb.tcb->conn.local.port;
  1642.         up->namelen = SOCKSIZE;
  1643.  
  1644.         sp.p = up->peername;
  1645.         sp.in->sin_family = AF_INET;
  1646.         sp.in->sin_addr.s_addr = up->cb.tcb->conn.remote.address;
  1647.         sp.in->sin_port = up->cb.tcb->conn.remote.port;
  1648.         up->peernamelen = SOCKSIZE;
  1649.  
  1650.         /* Wake up the guy accepting it, and let him run */
  1651.         psignal(oup,1);
  1652.         pwait(NULL);
  1653.         break;
  1654.     default:    /* Ignore all other state transitions */
  1655.         break;
  1656.     }
  1657.     psignal(up,0);    /* In case anybody's waiting */
  1658. }
  1659. /* Discard data received on a TCP connection. Used after a receive shutdown or
  1660.  * close_s until the TCB disappears.
  1661.  */
  1662. static void
  1663. trdiscard(tcb,cnt)
  1664. struct tcb *tcb;
  1665. int cnt;
  1666. {
  1667.     struct mbuf *bp;
  1668.  
  1669.     recv_tcp(tcb,&bp,(int16)cnt);
  1670.     free_p(bp);
  1671. }
  1672. #ifdef    AX25
  1673. /* AX.25 receive upcall */
  1674. void
  1675. s_arcall(axp,cnt)
  1676. struct ax25_cb *axp;
  1677. int cnt;
  1678. {
  1679.     int ns;
  1680.     struct usock *up,*nup,*oup;
  1681.     union sp sp;
  1682.  
  1683.     up = itop(axp->user);
  1684.     /* When AX.25 data arrives for the first time the AX.25 listener
  1685.        is notified, if active. If the AX.25 listener is a server its
  1686.        socket is duplicated in the same manner as in s_tscall().
  1687.      */
  1688.     if (Axi_sock != -1 && axp->user == -1) {
  1689.         oup = up = itop(Axi_sock);
  1690.         /* From now on, use the same upcalls as the listener */
  1691.         axp->t_upcall = up->cb.ax25->t_upcall;
  1692.         axp->r_upcall = up->cb.ax25->r_upcall;
  1693.         axp->s_upcall = up->cb.ax25->s_upcall;
  1694.         if (up->cb.ax25->flags.clone) {
  1695.             /* Clone the socket */
  1696.             ns = socket(AF_AX25,SOCK_STREAM,0);
  1697.             nup = itop(ns);
  1698.             ASSIGN(*nup,*up);
  1699.             axp->user = ns;
  1700.             nup->cb.ax25 = axp;
  1701.             /* Allocate new memory for the name areas */
  1702.             nup->name = mallocw(sizeof(struct sockaddr_ax));
  1703.             nup->peername = mallocw(sizeof(struct sockaddr_ax));
  1704.             /* Store the new socket # in the old one */
  1705.             up->rdysock = ns;
  1706.             up = nup;
  1707.         } else {
  1708.             axp->user = Axi_sock;
  1709.             del_ax25(up->cb.ax25);
  1710.             up->cb.ax25 = axp;
  1711.             /* Allocate space for the peer's name */
  1712.             up->peername = mallocw(sizeof(struct sockaddr_ax));
  1713.             /* Store the old socket # in the old socket */
  1714.             up->rdysock = Axi_sock;
  1715.         }
  1716.         /* Load the addresses. Memory for the name has already
  1717.          * been allocated, either above or in the original bind.
  1718.          */
  1719.         sp.p = up->name;
  1720.         sp.ax->sax_family = AF_AX25;
  1721.         memcpy(sp.ax->ax25_addr,axp->local,AXALEN);
  1722.         memcpy(sp.ax->iface,axp->iface->name,ILEN);
  1723.         up->namelen = sizeof(struct sockaddr_ax);
  1724.  
  1725.         sp.p = up->peername;
  1726.         sp.ax->sax_family = AF_AX25;
  1727.         memcpy(sp.ax->ax25_addr,axp->remote,AXALEN);
  1728.         memcpy(sp.ax->iface,axp->iface->name,ILEN);
  1729.         up->peernamelen = sizeof(struct sockaddr_ax);
  1730.         /* Wake up the guy accepting it, and let him run */
  1731.         psignal(oup,1);
  1732.         pwait(NULL);
  1733.         return;
  1734.     }
  1735.     /* Wake up anyone waiting, and let them run */
  1736.     psignal(up,1);
  1737.     pwait(NULL);
  1738. }
  1739. /* AX.25 transmit upcall */
  1740. void
  1741. s_atcall(axp,cnt)
  1742. struct ax25_cb *axp;
  1743. int cnt;
  1744. {
  1745.     /* Wake up anyone waiting, and let them run */
  1746.     psignal(itop(axp->user),1);
  1747.     pwait(NULL);
  1748. }
  1749. /* AX25 state change upcall routine */
  1750. void
  1751. s_ascall(axp,old,new)
  1752. register struct ax25_cb *axp;
  1753. int old,new;
  1754. {
  1755.     int s;
  1756.     struct usock *up;
  1757.  
  1758.     s = axp->user;
  1759.     up = itop(s);
  1760.  
  1761.     switch(new){
  1762.     case LAPB_DISCONNECTED:
  1763.         /* Clean up. If the user has already closed the socket,
  1764.          * then up will be null (s was set to -1 by the close routine).
  1765.          * If not, then this is an abnormal close (e.g., a reset)
  1766.          * and clearing out the pointer in the socket structure will
  1767.          * prevent any further operations on what will be a freed
  1768.          * control block. Also wake up anybody waiting on events
  1769.          * related to this block so they will notice it disappearing.
  1770.          */
  1771.         if(up != NULLUSOCK){
  1772.             up->errcodes[0] = axp->reason;
  1773.             up->cb.ax25 = NULLAX25;
  1774.         }
  1775.         del_ax25(axp);
  1776.         break;
  1777.     default:    /* Other transitions are ignored */
  1778.         break;
  1779.     }
  1780.     psignal(up,0);    /* In case anybody's waiting */
  1781. }
  1782. #endif
  1783. #ifdef NETROM
  1784. /* NET/ROM receive upcall routine */
  1785. static void
  1786. s_nrcall(cb,cnt)
  1787. struct nr4cb *cb;
  1788. int cnt;
  1789. {
  1790.     /* Wake up anybody waiting for data, and let them run */
  1791.     psignal(itop(cb->user),1);
  1792.     pwait(NULL);
  1793. }
  1794. /* NET/ROM transmit upcall routine */
  1795. static void
  1796. s_ntcall(cb,cnt)
  1797. struct nr4cb *cb;
  1798. int cnt;
  1799. {
  1800.     /* Wake up anybody waiting to send data, and let them run */
  1801.     psignal(itop(cb->user),1);
  1802.     pwait(NULL);
  1803. }
  1804. /* NET/ROM state change upcall routine */
  1805. static void
  1806. s_nscall(cb,old,new)
  1807. struct nr4cb *cb;
  1808. int old,new;
  1809. {
  1810.     int s,ns;
  1811.     struct usock *up,*nup,*oup;
  1812.     union sp sp;
  1813.  
  1814.     s = cb->user;
  1815.     oup = up = itop(s);
  1816.  
  1817.      if(new == NR4STDISC && up != NULLUSOCK){
  1818.         /* Clean up. If the user has already closed the socket,
  1819.          * then up will be null (s was set to -1 by the close routine).
  1820.          * If not, then this is an abnormal close (e.g., a reset)
  1821.          * and clearing out the pointer in the socket structure will
  1822.          * prevent any further operations on what will be a freed
  1823.          * control block. Also wake up anybody waiting on events
  1824.          * related to this cb so they will notice it disappearing.
  1825.          */
  1826.          up->cb.nr4 = NULLNR4CB;
  1827.          up->errcodes[0] = cb->dreason;
  1828.      }
  1829.      if(new == NR4STCON && old == NR4STDISC){
  1830.         /* Handle an incoming connection. If this is a server cb,
  1831.          * then we're being handed a "clone" cb and we need to
  1832.          * create a new socket structure for it. In either case,
  1833.          * find out who we're talking to and wake up the guy waiting
  1834.          * for the connection.
  1835.          */
  1836.         if(cb->clone){
  1837.             /* Clone the socket */
  1838.             ns = socket(AF_NETROM,SOCK_SEQPACKET,0);
  1839.             nup = itop(ns);
  1840.             ASSIGN(*nup,*up);
  1841.             cb->user = ns;
  1842.             nup->cb.nr4 = cb;
  1843.             cb->clone = 0; /* to avoid getting here again */
  1844.             /* Allocate new memory for the name areas */
  1845.             nup->name = mallocw(sizeof(struct sockaddr_nr));
  1846.             nup->peername = mallocw(sizeof(struct sockaddr_nr));
  1847.             /* Store the new socket # in the old one */
  1848.             up->rdysock = ns;
  1849.             up = nup;
  1850.             s = ns;
  1851.         } else {
  1852.             /* Allocate space for the peer's name */
  1853.             up->peername = mallocw(sizeof(struct sockaddr_nr));
  1854.             /* Store the old socket # in the old socket */
  1855.             up->rdysock = s;
  1856.         }
  1857.         /* Load the addresses. Memory for the name has already
  1858.          * been allocated, either above or in the original bind.
  1859.          */
  1860.         sp.p = up->name;
  1861.         sp.nr->nr_family = AF_NETROM;
  1862.         ASSIGN(sp.nr->nr_addr,up->cb.nr4->local);
  1863.         up->namelen = sizeof(struct sockaddr_nr);
  1864.  
  1865.         sp.p = up->peername;
  1866.         sp.nr->nr_family = AF_NETROM;
  1867.         ASSIGN(sp.nr->nr_addr,up->cb.nr4->remote);
  1868.         up->peernamelen = sizeof(struct sockaddr_nr);
  1869.  
  1870.         /* Wake up the guy accepting it, and let him run */
  1871.         psignal(oup,1);
  1872.         pwait(NULL);
  1873.     }
  1874.      /* Ignore all other state transitions */    
  1875.     psignal(up,0);    /* In case anybody's waiting */
  1876. }
  1877. #endif
  1878.  
  1879. /* Verify address family and length according to the socket type */
  1880. static int
  1881. checkaddr(type,name,namelen)
  1882. int type;
  1883. char *name;
  1884. int namelen;
  1885. {
  1886.     union sp sp;
  1887.  
  1888.     sp.p = name;
  1889.     /* Verify length and address family according to protocol */
  1890.     switch(type){
  1891.     case TYPE_TCP:
  1892.     case TYPE_UDP:
  1893.         if(sp.in->sin_family != AF_INET
  1894.          || namelen != sizeof(struct sockaddr_in))
  1895.             return -1;
  1896.         break;
  1897. #ifdef    AX25
  1898.     case TYPE_AX25I:
  1899.     case TYPE_AX25UI:
  1900.         if(sp.ax->sax_family != AF_AX25
  1901.          || namelen != sizeof(struct sockaddr_ax))
  1902.             return -1;
  1903.         break;
  1904. #endif
  1905. #ifdef    NETROM
  1906.     case TYPE_NETROML3:
  1907.     case TYPE_NETROML4:
  1908.         if(sp.nr->nr_family != AF_NETROM
  1909.          || namelen != sizeof(struct sockaddr_nr))
  1910.             return -1;
  1911.         break;
  1912. #endif
  1913.     }
  1914.     return 0;
  1915. }
  1916. /* Issue an automatic bind of a local address */
  1917. static void
  1918. autobind(s,af)
  1919. int s,af;
  1920. {
  1921.     char buf[MAXSOCKSIZE];
  1922.     union sp sp;
  1923.  
  1924.     sp.p = buf;
  1925.     switch(af){
  1926.     case AF_INET:
  1927.         sp.in->sin_family = AF_INET;
  1928.         sp.in->sin_addr.s_addr = INADDR_ANY;
  1929.         sp.in->sin_port = Lport++;
  1930.         bind(s,sp.p,sizeof(struct sockaddr_in));
  1931.         break;
  1932. #ifdef    AX25
  1933.     case AF_AX25:
  1934.         sp.ax->sax_family = AF_AX25;
  1935.         memset(sp.ax->ax25_addr,'\0',AXALEN);
  1936.         memset(sp.ax->iface,'\0',ILEN);
  1937.         bind(s,sp.p,sizeof(struct sockaddr_ax));
  1938.         break;
  1939. #endif
  1940. #ifdef    NETROM
  1941.     case AF_NETROM:
  1942.         sp.nr->nr_family = AF_NETROM;
  1943.         memcpy(sp.nr->nr_addr.user,Mycall,AXALEN);
  1944.         memcpy(sp.nr->nr_addr.node,Mycall,AXALEN);
  1945.         bind(s,sp.p,sizeof(struct sockaddr_nr));
  1946.         break;
  1947. #endif
  1948.     }
  1949. }
  1950.  
  1951. /* Return a pair of mutually connected sockets in sv[0] and sv[1] */
  1952. int
  1953. socketpair(af,type,protocol,sv)
  1954. int af;
  1955. int type;
  1956. int protocol;
  1957. int sv[];
  1958. {
  1959.     struct usock *up0, *up1;
  1960.     if(sv == NULLINT){
  1961.         errno = EFAULT;
  1962.         return -1;
  1963.     }
  1964.     if(af != AF_LOCAL){
  1965.         errno = EAFNOSUPPORT;
  1966.         return -1;
  1967.     }
  1968.     if(type != SOCK_STREAM && type != SOCK_DGRAM){
  1969.         errno = ESOCKTNOSUPPORT;
  1970.         return -1;
  1971.     }
  1972.     if((sv[0] = socket(af,type,protocol)) == -1)
  1973.         return -1;
  1974.     if((sv[1] = socket(af,type,protocol)) == -1){
  1975.         close_s(sv[0]);
  1976.         return -1;
  1977.     }
  1978.     up0 = itop(sv[0]);
  1979.     up1 = itop(sv[1]);
  1980.     up0->cb.local->peer = up1;
  1981.     up1->cb.local->peer = up0;
  1982.     return sv[1];
  1983. }
  1984.